function randomNum(maxNum: number) {
    return parseInt(String(Math.random() * (maxNum + 1)), 10);
}

// a为角度对应的边
function getTanDeg(a: number, b: number) {
    let deg = null;
    if (b !== 0) {
        deg = Math.atan(a / b) / (Math.PI / 180);
    }
    return deg;
}

function getNumArr(len: number) {
    const numArr = [];
    while (numArr.length < 25) {
        const num = randomNum(len - 1);
        if (numArr.indexOf(num) < 0) {
            numArr.push(num);
        }
    }
    return numArr;
}

class CnNum {
    //设置一些默认参数
    // private static UNIT_ARRAY = ['仟', '佰', '拾'];
    private static UNIT_ARRAY = ['千', '百', '十'];
    private static UNIT_ARRAY_OlD = ['拾']
    private static POINT = '点';
    private static NUM_ARRAY = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
    // private static NUM_ARRAY = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
    private static NUM_UNIT_ARRAY = ['万', '亿', '兆', '京', '垓', '秭', '穰', '沟', '涧', '正', '载', '极', '恒河沙', '阿僧祗', '那由他', '不可思议', '无量', '大数'];
    //匹配连续重复字符
    private static REG_DEL_REPEAT = /(.)\1+/g;
    //正向四位分割字符串
    private static REG_SPLIT_LEN = /(\d{4}(?=\d)(?!\d+\.|$))/g;
    //反向四位分割字符串
    private static REG_SPLIT_LEN_R = /(\d{1,4})(?=(?:\d{4})+(?!\d))/g;

    //转换成汉字
    /**
    * 格式化数字，方便后续处理
    * */
    private static formatNum(_NUM: any) {
        const iNum = parseInt(_NUM);
        if (iNum === 0) {
            return '0';
        }
        // 过滤掉不是数字的字符
        if (!_NUM || isNaN(_NUM)) return ''
        // 把类1.0，1.00格式的数字处理成1
        // 统一转成字符串
        if (+_NUM === iNum) return String(parseInt(_NUM))
        return String(_NUM)
    }

    //分割整数和小数部分
    private static dealNum(_NUM: any) {
        _NUM = this.formatNum(_NUM)
        return _NUM.split('.');
    }

    //每四位分割成一组
    private static splitNum(_NUM: any) {
        if (!_NUM || isNaN(_NUM)) return [];
        return _NUM.replace(this.REG_SPLIT_LEN_R, '$1,').split(',');
    }

    //转化四位数为汉字，加上单位
    private static switchNum(_NUM: any, isFirst: boolean) {
        // num 需要转换的数字
        // isFirst 是否为首位
        //最终返回结果的数组
        const res = [];
        if (!_NUM) return '';
        //不足四位的补足四位，以便补零
        const numArr = _NUM.split('').reverse().concat([0, 0, 0, 0]).splice(0, 4).reverse();
        numArr.map((n: any, i: number) => {
            if (!n || n == 0) {
                res.push((numArr[i + 1] == 0 || !numArr[i + 1] || isFirst) ? '' : this.NUM_ARRAY[n]);
            } else {
                res.push(this.NUM_ARRAY[n] + (n > 0 && i < 3 ? this.UNIT_ARRAY[i] : ''));
            }
        });
        return res.join('').replace(this.REG_DEL_REPEAT, '$1');
    }

    //转换小数部分
    private static switchDecimal(_NUM: any) {
        if (!_NUM) return;
        const res = [];
        const num = _NUM.split('');
        num.map(function (n: any, i: number) {
            if (!n || n == 0) {
                res.push((num[i + 1] == 0 || !num[i + 1]) ? '' : this.NUM_ARRAY[n]);
            } else {
                res.push(this.NUM_ARRAY[n]);
            }

        });
        return res.join('');
    }
    //转换成数字
    //分割整数和小数部分
    private static dealHz(_HZ: string) {
        if (!_HZ) return [];
        return _HZ.split(this.POINT);
    }
    //分割成组
    private static splitHz(_HZ: string) {
        if (!_HZ) return [0];
        //去掉整数部分所有的'零'，然后分割
        const arr = _HZ.replace(/零/g, '').split('');
        const res = [];
        let temp = '';
        let location = -10000;//设置一个超大数
        arr.map(function (n, i) {
            var thisLocation = this.NUM_UNIT_ARRAY.indexOf(n);
            if (thisLocation >= 0) {
                if (thisLocation - location < -1) {
                    for (var loc = 1; loc < location - thisLocation; loc++) {
                        res.push(this.NUM_ARRAY[0]);
                    }
                };
                res.push(temp);
                temp = '';
                location = thisLocation;
            } else {
                temp += n;
                if (i == _HZ.length - 1) res.push(temp);
            }
        });
        return res;
    }

    private static switchHz(_HZ: string) {
        if (!_HZ) return '';
        if (_HZ == this.NUM_ARRAY[0]) return '0000';
        const arr = _HZ.split('');
        let res = 0;
        let temp = 0;
        arr.map(function (n, i) {
            if (i % 2 == 0) {
                temp = this.NUM_ARRAY.indexOf(n);
                if (i == _HZ.length - 1) res += temp;
            } else {
                var z = 3 - this.UNIT_ARRAY.indexOf(n);
                res += (temp * Math.pow(10, z));
            }
        });
        return res;

    }
    //转换小数部分
    private static switchDecimalHz(_HZ: string) {
        if (!_HZ) return '';
        const arr = _HZ.split('');
        if (_HZ.length === 0) return '';
        const res = ['.'];
        arr.map(function (n) {
            res.push(this.NUM_ARRAY.indexOf(n));
        });
        return res.join('');
    }

    //拼接
    public static NumToHz(_NUM: any) {
        const numArr = this.dealNum(_NUM);
        const num = this.splitNum(numArr[0]);
        const len = num.length;
        let reslt = '';
        num.map((n: any, i: number) => {
            let temp = this.switchNum(n, i === 0);
            if (!temp) temp = this.NUM_ARRAY[0];
            if (len - 1 == i || temp == this.NUM_ARRAY[0]) {
                if (n < 20 && n >= 10) {
                    temp = temp.replace(new RegExp('^一'), '');
                }
                reslt += temp;
            } else {
                reslt += (temp + this.NUM_UNIT_ARRAY[len - i - 2]);
            }
        });
        reslt = reslt.replace(this.REG_DEL_REPEAT, '$1') + (!numArr[1] ? '' : (this.POINT + this.switchDecimal(numArr[1])))
        // reslt = reslt.replace(new RegExp(`${NUM_ARRAY[1]}${UNIT_ARRAY[2]}`, 'g'), UNIT_ARRAY[2])
        // .replace(new RegExp(`${UNIT_ARRAY[2]}`, 'g'), UNIT_ARRAY_OlD[0])
        return reslt;
    }

    public static HzToNum(_HZ: string) {
        if (!_HZ || _HZ == this.NUM_ARRAY[0]) return 0;
        const arr = this.dealHz(_HZ);
        const HZ_ARRAY = this.splitHz(arr[0]);
        const decimalPart = this.switchDecimalHz(arr[1]);
        let res = '';
        HZ_ARRAY.map(function (n) {
            const temp = this.switchHz(n);
            res = res + '' + temp;
        });
        return res + decimalPart;
    }
}